//Helper functions for interpolation
#ifndef _INTERPOLATION_H_
#define _INTERPOLATION_H_

namespace math
{
#include "vec2.h"

inline float LinearInt(float A, float B, float Factor)
{
	return B * Factor + A * (1.0f - Factor);
}



inline float QuadraticInt(float A, float B, float C, float Factor)
{
	float InvFactor = 1.0f - Factor;

	return C * Factor * Factor + B * 2.0f * Factor * InvFactor + A * InvFactor * InvFactor;
}


inline float CubicInt(float A, float B, float C, float D, float Factor)
{
	float InvFactor = 1.0f - Factor;

	return D * (Factor * Factor * Factor) + C * 3.0f * Factor * Factor * InvFactor + B * 3.0f * Factor * InvFactor * InvFactor + A * (InvFactor * InvFactor * InvFactor);

}



inline Vec2 CathmullRomVec2(const Vec2& p0, const Vec2& p1, const Vec2& p2, const Vec2& p3, float WeighingFactor)
{
//calculate weights given u
	float	u = WeighingFactor;
	float	uu = u*u;
	float	uuu = uu*u;
	float	w0 = -0.5f*uuu + uu - 0.5f*u;
	float	w1 = 1.5f*uuu - 2.5f*uu + 1;
	float	w2 = -1.5f*uuu + 2.0f*uu + 0.5f*u;
	float	w3 = 0.5f*uuu - 0.5f*uu;

	float	x = p0.x*w0 + p1.x*w1 + p2.x*w2 + p3.x*w3;
	float	y = p0.y*w0 + p1.y*w1 + p2.y*w2 + p3.y*w3;

//this is "the long version"
//var x = 0.5 *((2 * p1.x) + (-p0.x + p2.x)*u + (2*p0.x - 5*p1.x + 4*p2.x - p3.x)*uu + (-p0.x + 3*p1.x - 3*p2.x + p3.x)*uuu);
//var y = 0.5 *((2 * p1.y) + (-p0.y + p2.y)*u + (2*p0.y - 5*p1.y + 4*p2.y - p3.y)*uu + (-p0.y + 3*p1.y - 3*p2.y + p3.y)*uuu);

	return math::Vec2(x, y);
} 



inline Vec2 HermiteVec2(const Vec2& InPosition, const Vec2& InTangent, const Vec2& OutPosition, const Vec2& OutTangent, float WeighingFactor)
{
	float cube = WeighingFactor * WeighingFactor * WeighingFactor;
	float square = WeighingFactor * WeighingFactor;

	float Weight2 = -2 * cube + square;
	float Weight1 = -Weight2 + 1;
	float Weight3 = cube - (2 * square) + WeighingFactor;
	float Weight4 = cube - square;

	return Vec2(Weight1 * InPosition.x + Weight2 * InTangent.x + Weight3 * OutPosition.x + Weight4 * OutTangent.x,
			Weight1 * InPosition.y + Weight2 * InTangent.y + Weight3 * OutPosition.y + Weight4 * OutTangent.y);
} 


} // namespace math

#endif